package common

import (
	"alertmanagerWebhook/config"
	"alertmanagerWebhook/global"
	"alertmanagerWebhook/utils"
	"fmt"
	"time"

	"github.com/prometheus/alertmanager/template"
)

type MessageGenerator struct {
	redisUtil *utils.RedisUtil
	promUtil  *utils.PrometheusUtil // 新增Prometheus工具
}

func NewMessageGenerator() (*MessageGenerator, error) {
	redisUtil, err := utils.NewRedisUtil()
	if err != nil {
		global.Logger.Errorf("Failed to create Redis util: %v", err)
		return nil, fmt.Errorf("failed to create Redis util: %w", err)
	}
	return &MessageGenerator{
		redisUtil: redisUtil,
		promUtil:  utils.NewPrometheusUtil(), // 初始化Prometheus工具
	}, nil
}

func (g *MessageGenerator) generateContent(alert config.Alert, isResolved bool, receiver string) string {
	// 转换为template.Alert格式
	msg := template.Alert{
		Status:       "firing",
		Labels:       template.KV{},
		Annotations:  template.KV{},
		StartsAt:     alert.StartsAt,
		EndsAt:       alert.EndsAt,
		GeneratorURL: alert.GeneratorURL,
	}

	// 填充Labels
	msg.Labels["alertname"] = alert.Labels.Alertname
	msg.Labels["instance"] = alert.Labels.Instance
	msg.Labels["severity"] = alert.Labels.Severity
	if msg.Labels["severity"] == "" {
		msg.Labels["severity"] = "warning"
	}
	// 填充Annotations
	msg.Annotations["description"] = alert.Annotations.Description
	if msg.Annotations["description"] == "" {
		msg.Annotations["description"] = alert.Annotations.Summary
	}

	if isResolved {
		msg.Status = "resolved"
	}

	recM := map[string]string{"firing": "已触发", "resolved": "已恢复"}

	// 获取当前值 - 优化后的逻辑
	currentValue := "N/A"
	if msg.GeneratorURL != "" {
		// 修改Redis操作部分
		valueType := "firing_value"
		if isResolved {
			valueType = "resolved_value"
		}

		// 统一使用RedisUtil方法，内部会自动处理主从分离
		if val, err := g.redisUtil.HGet(alert.Fingerprint, valueType); err == nil && val != "" {
			currentValue = val
			global.Logger.Debugf("从Redis获取缓存值成功: %s", currentValue)
		} else {
			if val, err := g.promUtil.QueryCurrentValue(msg.GeneratorURL, alert); err == nil {
				currentValue = val
				global.Logger.Debugf("从Prometheus查询到的值: %s (告警指纹: %s)", val, alert.Fingerprint)
				if err := g.redisUtil.HSet(alert.Fingerprint, valueType, val); err != nil {
					global.Logger.Warnf("存储Redis值失败: %v (告警指纹: %s)", err, alert.Fingerprint)
				}
				if err := g.redisUtil.Expire(alert.Fingerprint, 3600); err != nil {
					global.Logger.Warnf("设置Redis过期时间失败: %v (告警指纹: %s)", err, alert.Fingerprint)
				}
			} else {
				global.Logger.Warnf("从Prometheus查询当前值失败: %v (告警指纹: %s)", err, alert.Fingerprint)
			}
		}
	}

	// 处理instance为空的情况
	instance := msg.Labels["instance"]
	if instance == "" {
		// 尝试从其他标签获取替代信息
		if job := msg.Labels["job"]; job != "" {
			instance = "K8s Job: " + job
		} else if pod := msg.Labels["pod"]; pod != "" {
			instance = "Pod: " + pod
		} else if namespace := msg.Labels["namespace"]; namespace != "" {
			instance = "Namespace: " + namespace
		} else if service := msg.Labels["service"]; service != "" {
			instance = "Service: " + service
		} else {
			instance = "N/A"
		}
	}

	// 统一使用兼容三个平台的格式
	return fmt.Sprintf(
		"%s--%s        \n"+
			"**规则名称**: %s        \n"+
			"**状态**: %s        \n"+
			"**告警级别**: %s        \n"+
			"**首次触发时间**: %s        \n"+
			"**%s时间**: %s        \n"+
			"**%s次数**: %d        \n"+
			"**目标机器**: %s        \n"+
			"**%s详情**: %s        \n"+
			"**当前值**: %s        \n"+
			"**通知渠道**: %s        \n",
		global.Config.System.ProjectName,
		map[bool]string{true: "故障恢复", false: "故障告警"}[isResolved],
		msg.Labels["alertname"],
		recM[msg.Status],
		msg.Labels["severity"],
		msg.StartsAt.In(time.Local).Format("2006-01-02 15:04:05"),
		map[bool]string{true: "恢复", false: "再次触发"}[isResolved],
		map[bool]string{
			true:  msg.EndsAt.In(time.Local).Format("2006-01-02 15:04:05"),
			false: time.Now().Format("2006-01-02 15:04:05"),
		}[isResolved],
		map[bool]string{true: "恢复", false: "告警"}[isResolved],
		map[bool]int{
			true:  alert.Count,
			false: alert.Count,
		}[isResolved],
		instance, // 使用处理后的instance值
		map[bool]string{true: "恢复", false: "告警"}[isResolved],
		msg.Annotations["description"],
		currentValue,
		receiver,
	)
}

// 修改GenerateAlertContent方法，添加平台参数
func (g *MessageGenerator) GenerateAlertContent(notification config.Notification, platform string) (string, string, error) {
	defer g.redisUtil.Close()

	var firingContent, resolvedContent string
	cstZone := time.FixedZone("CST", 8*3600)

	for _, alert := range notification.Alerts {
		alert.StartTime = alert.StartsAt.In(cstZone).Format("2006-01-02 15:04:05")

		if alert.Status == "firing" {
			if err := g.processFiringAlert(&alert); err != nil {
				return "", "", err
			}

			firingContent += g.generateContent(alert, false, notification.Receiver)

		} else if alert.Status == "resolved" {
			g.processResolvedAlert(&alert)

			resolvedContent += g.generateContent(alert, true, notification.Receiver)

		}
	}

	return firingContent, resolvedContent, nil
}

func (g *MessageGenerator) processFiringAlert(alert *config.Alert) error {
	var err error
	if global.Config.Redis.Mode == "master-slave" {
		// 主从架构下使用读写分离API
		if err = utils.HSetWritable(alert.Fingerprint, "startTime", alert.StartTime); err != nil {
			return fmt.Errorf("failed to set start time in redis: %w", err)
		}
		if err = utils.HSetWritable(alert.Fingerprint, "generatorURL", alert.GeneratorURL); err != nil {
			return fmt.Errorf("failed to set generatorURL in redis: %w", err)
		}
		if err = utils.HIncrByWritable(alert.Fingerprint, "count", 1); err != nil {
			return fmt.Errorf("failed to increment count in redis: %w", err)
		}
	} else {
		// 单节点或集群模式下使用原有方式
		if err = g.redisUtil.HSet(alert.Fingerprint, "startTime", alert.StartTime); err != nil {
			return fmt.Errorf("failed to set start time in redis: %w", err)
		}
		if err = g.redisUtil.HSet(alert.Fingerprint, "generatorURL", alert.GeneratorURL); err != nil {
			return fmt.Errorf("failed to set generatorURL in redis: %w", err)
		}
		if err = g.redisUtil.HIncrBy(alert.Fingerprint, "count", 1); err != nil {
			return fmt.Errorf("failed to increment count in redis: %w", err)
		}
	}

	// 获取计数逻辑也需要区分模式
	var count int
	if global.Config.Redis.Mode == "master-slave" {
		count, err = utils.HGetIntReadable(alert.Fingerprint, "count")
	} else {
		count, err = g.redisUtil.HGetInt(alert.Fingerprint, "count")
	}
	if err != nil {
		return fmt.Errorf("failed to get alert count: %w", err)
	}
	alert.Count = count

	if alert.Annotations.Description == "" {
		alert.Annotations.Description = alert.Annotations.Summary
	}
	if alert.Labels.Severity == "" {
		alert.Labels.Severity = "warning"
	}

	return nil
}

func (g *MessageGenerator) processResolvedAlert(alert *config.Alert) {
	// 获取告警次数
	var count int
	var err error
	if global.Config.Redis.Mode == "master-slave" {
		count, err = utils.HGetIntReadable(alert.Fingerprint, "count")
	} else {
		count, err = g.redisUtil.HGetInt(alert.Fingerprint, "count")
	}
	if err == nil {
		alert.Count = count
	}

	// 获取存储的generatorURL
	var url string
	if global.Config.Redis.Mode == "master-slave" {
		url, err = utils.HGetReadable(alert.Fingerprint, "generatorURL")
	} else {
		url, err = g.redisUtil.HGet(alert.Fingerprint, "generatorURL")
	}
	if err == nil {
		alert.GeneratorURL = url
	}
	alert.EndTime = alert.EndsAt.In(time.FixedZone("CST", 8*3600)).Format("2006-01-02 15:04:05")
}

func (g *MessageGenerator) ConfirmAlertResolution(fingerprint string) error {
	fields := []string{
		"startTime", "generatorURL", "count",
		"firing_value", "resolved_value",
	}

	var err error
	for _, field := range fields {
		var e error
		e = g.redisUtil.HDel(fingerprint, field)
		if e != nil {
			err = e
		}
	}
	return err
}
